package threading;

class MyBlockingQueue {
    private int[] elems = new int[1000];
    //加volatile的原因是在多个线程的调度中可能会出现错误
    volatile private int head = 0;
    volatile private int tail = 0;
    volatile private int size = 0;


   synchronized public void put(int elem) throws InterruptedException {
       //用while而不用if的原因是在别的线程中可能会有interrupt,导致wait被提前唤醒
         while (size == elems.length) {
             this.wait();
         }
         elems[tail] = elem;
         tail++;
         if (tail == elems.length) {
             tail = 0;
         }
           size++;
           this.notify();
     }

    synchronized public Integer take() throws InterruptedException {
        while (size == 0) {
            this.wait();;
        }
        int value = elems[head];
        head++;

        if (head == elems.length) {
            head = 0;
        }
        size--;
        this.notify();
        return value;
     }


}
public class ThreadDemo22 {
    public static void main(String[] args) {
        MyBlockingQueue myBlockingQueue = new MyBlockingQueue();

        Thread t1 = new Thread( () -> {
            while (true) {
                try {
                    int value = myBlockingQueue.take();
                    System.out.println("消费者" + value);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread( () -> {
            int count = 0;
            while (true) {
                try {
                    System.out.println("生产者" + count);
                    myBlockingQueue.put(count);
                    Thread.sleep(1000);
                    count++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        t2.start();
    }
}
